{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## _*Using Qiskit Aqua's quantum evolution functionality*_\n",
    "\n",
    "This notebook demonstrates how to realize quantum evolution using the `Qiskit Aqua` library.\n",
    "\n",
    "Further information is available for the algorithms in the github repo aqua/readme.md\n",
    "\n",
    "First, an WeightedPauliOperator instance is created for our randomly generated Hamiltonian. We also randomly generate an initial quantum state `state_in`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy.linalg import expm\n",
    "from qiskit import BasicAer\n",
    "from qiskit import execute as q_execute\n",
    "from qiskit import QuantumCircuit, QuantumRegister\n",
    "from qiskit.quantum_info import state_fidelity\n",
    "from qiskit.aqua.operators import MatrixOperator, op_converter\n",
    "from qiskit.aqua.components.initial_states import Custom\n",
    "\n",
    "num_qubits = 2\n",
    "evo_time = 1\n",
    "temp = np.random.random((2 ** num_qubits, 2 ** num_qubits))\n",
    "h1 = temp + temp.T\n",
    "qubitOp = MatrixOperator(matrix=h1)\n",
    "state_in = Custom(num_qubits, state='random')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With the operator and the initial state, we can easily compute the groundtruth evolution result as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The directly computed groundtruth evolution result state is\n",
      "[-0.52115696+0.33380779j -0.03365282+0.24949932j -0.53816051+0.37654038j\n",
      " -0.33346721-0.10481218j].\n"
     ]
    }
   ],
   "source": [
    "state_in_vec = state_in.construct_circuit('vector')\n",
    "groundtruth = expm(-1.j * h1 * evo_time) @ state_in_vec\n",
    "print('The directly computed groundtruth evolution result state is\\n{}.'.format(groundtruth))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `evolve` method as provided by the `MatrixOperator` class also provides the ability to compute the evolution groundtruth via the same matrix and vector multiplication. Therefore, we can also compute the evolution's groundtruth result state as follows, which we can easily verify to be the same as the `groundtruth` we just computed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The groundtruth evolution result as computed by the Dynamics algorithm is\n",
      "[-0.52115696+0.33380779j -0.03365282+0.24949932j -0.53816051+0.37654038j\n",
      " -0.33346721-0.10481218j].\n"
     ]
    }
   ],
   "source": [
    "groundtruth_evolution = qubitOp.evolve(state_in_vec, evo_time, num_time_slices=0)\n",
    "print('The groundtruth evolution result as computed by the Dynamics algorithm is\\n{}.'.format(groundtruth_evolution))\n",
    "np.testing.assert_allclose(groundtruth_evolution, groundtruth)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, let's actually build the quantum circuit, which involves the circuit for putting the system in the specified initial state, and the actual `evolution` circuit corresponding to the operator we generated, for which, let's, for example, use the `3`rd order `suzuki` expansion.\n",
    "\n",
    "Furthermore, we need to convert `MatrixOperator` to `WeightedPauliOperator` to generate circuits for quantum device."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "qubit_op = op_converter.to_weighted_pauli_operator(qubitOp)\n",
    "\n",
    "quantum_registers = QuantumRegister(qubit_op.num_qubits)\n",
    "circuit = state_in.construct_circuit('circuit', quantum_registers)\n",
    "circuit += qubit_op.evolve(\n",
    "    None, evo_time, num_time_slices=1,\n",
    "    quantum_registers=quantum_registers,\n",
    "    expansion_mode='suzuki',\n",
    "    expansion_order=3\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 635.213x144.48 with 1 Axes>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circuit.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With the circuit built, we can now execute the circuit to get the evolution result. We use the `statevector_simulator` backend for the purpose of this demonstration."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The evolution result state from executing the Dynamics circuit is\n",
      "[ 0.46878654-0.40381906j -0.00219014-0.25176808j  0.47989299-0.44857662j\n",
      "  0.34500974+0.05681016j].\n"
     ]
    }
   ],
   "source": [
    "backend = BasicAer.get_backend('statevector_simulator')\n",
    "job = q_execute(circuit, backend)\n",
    "circuit_execution_result = np.asarray(job.result().get_statevector(circuit))\n",
    "print('The evolution result state from executing the Dynamics circuit is\\n{}.'.format(circuit_execution_result))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then check the fidelity between the `groundtruth` and the `circuit_execution_result`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fidelity between the groundtruth and the circuit result states is 0.9999998118796289.\n"
     ]
    }
   ],
   "source": [
    "print('Fidelity between the groundtruth and the circuit result states is {}.'.format(\n",
    "    state_fidelity(groundtruth, circuit_execution_result)\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As seen, the fidelity is very close to `1`, indicating that the quantum circuit produced is a good approximation of the intended evolution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
